package com.morristaedt.mirror.ui;

import android.content.Context;
import android.graphics.PointF;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.res.ResourcesCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.affectiva.android.affdex.sdk.Frame;
import com.affectiva.android.affdex.sdk.detector.Face;
import com.morristaedt.mirror.MirrorApplication;
import com.morristaedt.mirror.R;
import com.morristaedt.mirror.bean.FacePlusResult;
import com.morristaedt.mirror.modules.emotion.FaceModule;
import com.morristaedt.mirror.widget.MetricDisplay;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 人脸识别展示fragment
 */
public class FaceFragment extends Fragment {

    private static final String TAG = "FaceFragment";


    private TextView mTvFace;
    private TextView mTvFacePlus;
    private ImageView mIvEmoji;

    private FaceModule mFaceModule;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    public static final int NUM_METRICS_DISPLAYED = 6;
    private boolean hadSayHi = false;
    private LinearLayout llMetric;
    private MetricDisplay[] metricDisplays;
    private static final String[] DEFAULT_METRIC = {"开心", "伤心", "生气", "惊喜", "厌烦", "专注"};

    private Map<String,Integer> ageMap = new HashMap<>();
    public FaceFragment() {
    }

    public static FaceFragment newInstance() {
        FaceFragment fragment = new FaceFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mFaceModule = new FaceModule(getActivity(), faceListener);
        mFaceModule.startDetection();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_face, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mTvFace = (TextView) view.findViewById(R.id.tv_face);
        mTvFacePlus = (TextView) view.findViewById(R.id.tv_face_plus);
        mIvEmoji = (ImageView) view.findViewById(R.id.iv_emoji);
        llMetric = (LinearLayout) view.findViewById(R.id.ll_metrics);
        //Initialize views to display metrics 情绪百分比参数展示view
        TextView[] metricNames = new TextView[NUM_METRICS_DISPLAYED];
        metricNames[0] = (TextView) view.findViewById(R.id.metric_name_0);
        metricNames[1] = (TextView) view.findViewById(R.id.metric_name_1);
        metricNames[2] = (TextView) view.findViewById(R.id.metric_name_2);
        metricNames[3] = (TextView) view.findViewById(R.id.metric_name_3);
        metricNames[4] = (TextView) view.findViewById(R.id.metric_name_4);
        metricNames[5] = (TextView) view.findViewById(R.id.metric_name_5);
        metricDisplays = new MetricDisplay[NUM_METRICS_DISPLAYED];
        metricDisplays[0] = (MetricDisplay) view.findViewById(R.id.metric_pct_0);
        metricDisplays[1] = (MetricDisplay) view.findViewById(R.id.metric_pct_1);
        metricDisplays[2] = (MetricDisplay) view.findViewById(R.id.metric_pct_2);
        metricDisplays[3] = (MetricDisplay) view.findViewById(R.id.metric_pct_3);
        metricDisplays[4] = (MetricDisplay) view.findViewById(R.id.metric_pct_4);
        metricDisplays[5] = (MetricDisplay) view.findViewById(R.id.metric_pct_5);

        // 百分比的显示字体
        Typeface face = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Square.ttf");
        for (int i = 0; i < DEFAULT_METRIC.length; i++) {
            // 设置名称
            metricNames[i].setText(DEFAULT_METRIC[i]);
            metricDisplays[i].setTypeface(face);
        }

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mFaceModule != null) {
            mFaceModule.stopDetection();
        }
    }

    /**
     * 人脸识别的监听回调
     */
    private FaceModule.FaceDetectedListener faceListener = new FaceModule.FaceDetectedListener() {

        @Override
        public void onFacePlusResponse(FacePlusResult facePlus) {
            List<FacePlusResult.FacesBean> faces = facePlus.getFaces();
            Log.i(TAG, "face++ run: "+faces.size());
            if (faces.size()>0){
                final FacePlusResult.FacesBean.AttributesBean faceAttr = faces.get(0).getAttributes();

                Log.i(TAG, "run: "+faceAttr.getAge() + "  "+faceAttr.getSkinstatus().toString());
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTvFacePlus.setVisibility(View.VISIBLE);
                        mTvFacePlus.setText(faceAttr.toString());
                    }
                });
            }
        }

        private Context context = MirrorApplication.getInstance();

        /**
         * 检测到人脸
         */
        @Override
        public void onFaceDetectionStarted() {
            if (!hadSayHi) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTvFace.setVisibility(View.VISIBLE);
                        mTvFace.setText("你好~");
                        hadSayHi = true;
                    }
                });

            }
        }

        @Override
        public void onFaceDetectionStopped() {

        }

        @Override
        public void onImageResults(List<Face> faces, Frame frame, float v) {
            if (faces == null || faces.size() == 0) { //没脸
                return;
            }
            //有脸
            final Face face = faces.get(0);
//            Log.d(TAG, "valence score = " + Float.toString(face.emotions.getValence()));
            mHandler.post(new Runnable() {  //UI 主线程执行
                @Override
                public void run() {
                    showFaceContent(face, context);
                }
            });
        }
    };

    //        增加一个对收到年龄字符串的处理函数, 已经处理过的年龄存起来，下次在还这个区间就直接用
    int ShowAge(String ageValue) {
        if (ageMap.containsKey(ageValue)){
            return ageMap.get(ageValue);
        }
        String front = ageValue.split("_")[1];
        String later = ageValue.split("_")[2];
        int a, b;
        Random rand = new Random();
        a = Integer.parseInt(front);
        b = Integer.parseInt(later);
        int age = rand.nextInt(b - a + 1) + a;
        ageMap.put(ageValue,age);
        return age;
    }

    private void showFaceContent(Face face, Context context) {
        int faceId = face.getId();

        //Appearance
        Face.GENDER genderValue = face.appearance.getGender();
        Face.GLASSES glassesValue = face.appearance.getGlasses();
        Face.AGE ageValue = face.appearance.getAge();
        Face.ETHNICITY ethnicityValue = face.appearance.getEthnicity();

        StringBuilder sb = new StringBuilder();
        // 性别
        if (genderValue != Face.GENDER.UNKNOWN) {
            sb.append(genderValue.name());
        }

        //年龄
        if (ageValue != Face.AGE.AGE_UNKNOWN) {
            sb.append("\n").append("年龄：").append(ShowAge(ageValue.name()));
        }


        // 表情对应的emoji
        String emojiName = face.emojis.getDominantEmoji().name();
        if (!emojiName.equals(Face.EMOJI.UNKNOWN.name())) {

            mIvEmoji.setVisibility(View.VISIBLE);
            String drawable_emoji = emojiName.toLowerCase() + "_emoji";
            int id = getDrawable(context, drawable_emoji);
            sb.append("\n emoji:").append(emojiName);
            if (id > 0) {
                mIvEmoji.setImageDrawable(ResourcesCompat.getDrawable(getResources(), id, null));
            }
        }

        //Some Emoji
        float smiley = face.emojis.getSmiley();
        float laughing = face.emojis.getLaughing();
        float wink = face.emojis.getWink();
        sb.append("\n微笑值：").append(smiley)
                .append("\n").append("放松值：").append(face.emojis.getRelaxed());
        //Some Emotions
        float joy = face.emotions.getJoy();
        float sadness = face.emotions.getSadness();
        float anger = face.emotions.getAnger();
        float disgust = face.emotions.getDisgust();
        float surprise = face.emotions.getSurprise();
        sb.append("\n喜悦值：").append(joy)
                .append("\n").append("生气值：").append(anger)
                .append("\n").append("厌烦值：").append(disgust);


        //Some Expressions
        float smile = face.expressions.getSmile();
        float brow_furrow = face.expressions.getBrowFurrow();
        float brow_raise = face.expressions.getBrowRaise();
        float attention = face.expressions.getAttention();

        //Measurements
        float interocular_distance = face.measurements.getInterocularDistance();
        float yaw = face.measurements.orientation.getYaw();
        float roll = face.measurements.orientation.getRoll();
        float pitch = face.measurements.orientation.getPitch();

        //Face feature points coordinates
        PointF[] points = face.getFacePoints();

        // 情绪动态矩形条展示
        metricDisplays[0].setScore(joy);
        metricDisplays[1].setScore(sadness);
        metricDisplays[2].setScore(anger);
        metricDisplays[3].setScore(surprise);
        metricDisplays[4].setScore(disgust);
        metricDisplays[5].setScore(attention);
        if (hadSayHi && !TextUtils.isEmpty(sb.toString().trim())) {
            mTvFace.setText(sb.toString());
            llMetric.setVisibility(View.VISIBLE);

        } else {
            llMetric.setVisibility(View.GONE);
        }
    }


    /**
     * 根据资源名获取id
     */
    private static int getDrawable(Context context, String name) {
        if (context == null) {
            return 0;
        }
        return context.getResources().getIdentifier(name, "drawable", context.getPackageName());
    }
}

